﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
namespace Project.Yan.Net.DAL
{
    public class Repository<T> : IRepository<T> where T : class
    {
        /// <summary>
        /// 数据库上下文实例
        /// </summary>
        protected readonly AppDbContext _context;

        /// <summary>
        /// 数据集实例，用于操作泛型类型 T 的数据
        /// </summary>
        protected readonly DbSet<T> _dbSet;

        /// <summary>
        /// 初始化 Repository 类的实例
        /// </summary>
        /// <param name="context">数据库上下文实例</param>
        public Repository(AppDbContext context)
        {
            _context = context;
            _dbSet = context.Set<T>();
        }

        /// <summary>
        /// 根据 ID 异步获取单个实体
        /// </summary>
        /// <param name="id">实体的 ID</param>
        /// <returns>找到的实体，如果未找到则返回 null</returns>
        public async Task<T> GetByIdAsync(int id) => await _dbSet.FindAsync(id);

        /// <summary>
        /// 异步根据传入条件获取单个实体
        /// </summary>
        /// <param name="predicate">查询条件的表达式</param>
        /// <returns>找到的实体，如果未找到则返回 null</returns>
        public async Task<T> GetFirstOrDefaultAsync(Expression<Func<T, bool>> predicate)
        {
            return await _dbSet.FirstOrDefaultAsync(predicate);
        }
        /// <summary>
        /// 异步获取所有实体，不进行跟踪更改
        /// </summary>
        /// <returns>实体集合</returns>
        public async Task<IEnumerable<T>> GetAllAsync() => await _dbSet.AsNoTracking().ToListAsync();

        /// <summary>
        /// 根据条件异步查找实体，不进行跟踪更改
        /// </summary>
        /// <param name="predicate">用于筛选的条件表达式</param>
        /// <returns>符合条件的实体集合</returns>
        public async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate)
            => await _dbSet.Where(predicate).AsNoTracking().ToListAsync();

        /// <summary>
        /// 异步添加单个实体到数据集
        /// </summary>
        /// <param name="entity">要添加的实体</param>
        public async Task AddAsync(T entity) => await _dbSet.AddAsync(entity);

        /// <summary>
        /// 异步添加多个实体到数据集
        /// </summary>
        /// <param name="entities">要添加的实体集合</param>
        public async Task AddRangeAsync(IEnumerable<T> entities) => await _dbSet.AddRangeAsync(entities);

        /// <summary>
        /// 更新单个实体
        /// </summary>
        /// <param name="entity">要更新的实体</param>
        public void Update(T entity) => _dbSet.Update(entity);

        /// <summary>
        /// 从数据集中移除单个实体
        /// </summary>
        /// <param name="entity">要移除的实体</param>
        public void Remove(T entity) => _dbSet.Remove(entity);

        /// <summary>
        /// 从数据集中移除多个实体
        /// </summary>
        /// <param name="entities">要移除的实体集合</param>
        public void RemoveRange(IEnumerable<T> entities) => _dbSet.RemoveRange(entities);

        /// <summary>
        /// 异步保存对数据集所做的更改
        /// </summary>
        /// <returns>受影响的行数</returns>
        public async Task<int> SaveChangesAsync() => await _context.SaveChangesAsync();
    }


}
